/*********************************************************************************
Class Name: NMRCreateUpdateOpptyfromProposal
Author: Accenture IDC
Date:4/17/2012 
Requirement/Project Name: NMR  
Requirement Description:  Create or Update Opportunity for the incoming Proposal
Version History: Created
**********************************************************************************/
Public Class NMRCreateUpdateOpptyfromProposal{
    /**
        method called in a trigger of Proposal Summary Object to search for opportunity or 
        create new opportunity if not found
     **/
    public static Id nmrOpptyRecordTypeID = RecordTypeHelper.GetRecordTypeID('Opportunity', 'NMR Opportunity');
    public static Id NMRNotesRT = RecordTypeHelper.GetRecordTypeID('Notes__c', 'NMR Notes');
    Public static void createOppty(set<string> csscustidSet,set<string> attuidSet,Map<String,Proposal_Summary__c> proposalMap){
        Set<string> UserIds = new Set<string>();//To store OwnerIds of the proposals
        List<Opportunity> opptyList = new List<Opportunity>();//To store the retrieved opportunity List
        List<Opportunity> opptytoUpdate = new List<Opportunity>();//The Opportunities to update
        OpptyList = selectOppty(csscustidSet,attuidSet);// Method called to get the opportunity list as per ATTUID and CSSCustId
        Set<String> attStr = new Set<String>();
        Set<String> custStr = new Set<String>();
        List<Notes__c> notesToAttach = new List<Notes__c>();
        
        //Loop through the Opportunity List and set the OpportunityId at the Proposal and stage change of Opportunity
        for(opportunity oppty:opptyList){
            string attcssstring = (oppty.secondary_owner__r.ATTUID__c+oppty.account.CSS_CustomerID__c).toLowerCase();
            if(proposalMap.containsKey(attcssstring)){
                proposalMap.get(attcssstring).Opportunity_Id__c = oppty.Id;
                if(!NMRUtil.ISEmpty(oppty.AccountId)){
                    proposalMap.get(attcssstring).Account_Id__c = oppty.AccountId;
                }
                if(oppty.Override_Amount__c == NULL){
                        oppty.Override_Amount__c = proposalMap.get(attcssstring).Proposal_NISD_Amount__c;
                        oppty.Customer_ID__c = oppty.account.CSS_CustomerID__c;
                        
                    }
                    oppty.Disposition__c = 'Proposal Created';//Change of Opportunity Stage via workflow when Disposition is set to Proposal Created.
                    opptytoUpdate.add(oppty);
                proposalMap.remove(attcssstring);
                
            }
        }
        for(Proposal_Summary__c propVar:proposalMap.Values()){
          attStr.add(propVar.Proposal_Rep_ATTUID__c.toLowerCase());
          custStr.add(propVar.Customer_ID__c.toLowerCase());
       } 

        if(proposalMap.size()>0){
            createOpptyforProposal(attStr,custStr,proposalMap);
        }
        if(opptytoUpdate.size()>0){
            try{
                update opptytoUpdate;
                //Create Notes
                for(Opportunity opp: opptytoUpdate){
                    Notes__c newNotes = new Notes__c();
                    newNotes.Type__c = 'Salesforce';
                    newNotes.Follow_Up__c = date.today();
                    newNotes.Opportunity_Disposition__c = 'Proposal Created';
                    newNotes.Opportunity__c = opp.Id;
                    newNotes.OwnerId =  opp.OwnerId;
                    newNotes.RecordTypeid = NMRNotesRT;
                    notesToAttach.add(newNotes);
                }
                if(notesToAttach.size()>0){
                    try{ 
                          insert notesToAttach;
                    }
                    catch(Exception ex){
                         system.debug(ex);
                     }
                 }
            }
            catch(DMLException ex){
                        system.debug('DML Exception thrown while creating oppty'+ex);
             }
        }
    }
    /**************************
    *  Method to create an Opportunity during cases where no Open Opportunities exist for
    *  the specific Opportunity record.
    *
    **************************/
    Public Static void createOpptyforProposal(Set<String> attStr,Set<String> custStr,Map<string,Proposal_Summary__c> proposalMap){
            List<Notes__c> notesToCreate = new List<Notes__c>();
            Map<string,Opportunity> opptytoCreate = new Map<string,Opportunity>();
            Map<string,Account> accountIdCustMap = new  Map<string,Account>(); //Accounts that match the Customer Id in Proposal records
            //Map<string,Id> userIdattMap = new  Map<string,Id>();// User records that match against the ATTUId specified in the Proposal Records.
            Map<string,User> userIdattMap = new  Map<string,User>();
            List<Opportunity> opptycreateList = new List<Opportunity>();
            Id NMRAccountRT = RecordTypeHelper.GetRecordTypeID('Account', 'CSS Customer');
            //Id NMRNotesRT = RecordTypeHelper.GetRecordTypeID('Notes__c', 'NMR Notes');

                for(account acc:[select name,id,CSS_CustomerID__c,CSS_ListingTel__c from account where CSS_CustomerID__c IN:  custStr AND RecordtypeId =: NMRAccountRT]){
                    accountIdCustMap.put(acc.CSS_CustomerID__c.toLowerCase(),acc);
                }
                for(User usr: [Select id,ATTUID__c,ManagerId from User where ATTUID__c in: attStr]){
                    userIdattMap.put(usr.ATTUID__c.toLowerCase(),usr);
                }
                
        for(string pSummary:proposalMap.keySet()){
          if(proposalMap.get(pSummary) != NULL){
                    Proposal_Summary__c prop = new Proposal_Summary__c();
                    prop = proposalMap.get(pSummary);
                    Opportunity opp = new  Opportunity();
                    opp.name = accountIdCustMap.get(prop.Customer_ID__c).Name; //Name of the Opportunity set as the Account Name.
                    opp.CloseDate = System.Today()+30;
                    //opp.phone__c = accountIdCustMap.get(prop.Customer_ID__c).CSS_ListingTel__c;
                    opp.accountId = accountIdCustMap.get(prop.Customer_ID__c).Id;
                    opp.stagename = 'Stage 1 - Proposal Created';
                    opp.Customer_ID__c = prop.Customer_ID__c;
                    opp.Disposition__c = 'Proposal Created';
                    opp.Amount = prop.Proposal_NISD_Amount__c;
                    opp.RecordTypeId = nmrOpptyRecordTypeID;
                    string attidstr = prop.Proposal_Rep_ATTUID__c.toLowerCase();
                    if(userIdattMap.get(attidstr).ManagerId!=Null){
                        opp.OwnerId = userIdattMap.get(attidstr).ManagerId;
                        opp.secondary_owner__c = userIdattMap.get(attidstr).Id;
                    }
                    else{
                        opp.OwnerId = userIdattMap.get(attidstr).Id;
                        opp.secondary_owner__c = userIdattMap.get(attidstr).Id;
                    }
                    opptytoCreate.put(prop.Proposal_Rep_ATTUID__c.toLowerCase()+prop.Customer_ID__c.toLowerCase(),opp);
           }
                }
               
                if(opptytoCreate.size()>0){
                    try{
                        Insert opptytoCreate.values();
                         for(string propVar:proposalMap.keySet()){
                if(opptytoCreate.get(proposalMap.get(propVar).proposal_Rep_ATTUID__c.toLowerCase()+proposalMap.get(propVar).Customer_ID__c.toLowerCase()) != NULL){
                                    proposalMap.get(propVar).Opportunity_Id__c = opptytoCreate.get(proposalMap.get(propVar).Proposal_Rep_ATTUID__c.toLowerCase()+proposalMap.get(propVar).Customer_ID__c.toLowerCase()).Id;
                                    proposalMap.get(propVar).Account_Id__c = opptytoCreate.get(proposalMap.get(propVar).Proposal_Rep_ATTUID__c.toLowerCase()+proposalMap.get(propVar).Customer_ID__c.toLowerCase()).AccountId;
                                    Notes__c newNote = new Notes__c();
                                    newNote.Type__c = 'Salesforce';
                                    newNote.Follow_Up__c = date.today();
                                    newNote.Opportunity_Disposition__c = 'Proposal Created';
                                    newNote.Opportunity__c = opptytoCreate.get(proposalMap.get(propVar).Proposal_Rep_ATTUID__c.toLowerCase()+proposalMap.get(propVar).Customer_ID__c.toLowerCase()).Id;
                                    newNote.OwnerId =  opptytoCreate.get(proposalMap.get(propVar).Proposal_Rep_ATTUID__c.toLowerCase()+proposalMap.get(propVar).Customer_ID__c.toLowerCase()).OwnerId;
                                    newNote.RecordTypeid = NMRNotesRT;
                                    notesToCreate.add(newNote);                           
                                    }
                         }
                         if(notesToCreate.size()>0){
                             try{ 
                                 insert notesToCreate;
                             }
                             catch(Exception ex){
                                 system.debug(ex);
                             }
                             }
                         }    
                    catch(DMLException e){
                        system.debug('DML Exception thrown'+e);
                    }
                }
                
    }
    /**********************
    *  Method to identify the List of Opportunities to which the Proposal record
    *  needs to be attached to.
    *  Only Open/New Opportunities will be selected.
    ***********************/
    
    Public Static List<Opportunity> selectOppty(set<string> csscustidSet,set<string> attuidSet){
        List<Opportunity> OpptyListSelected = new List<Opportunity>(); //List of Opportunities that got selected.
       
        for(Opportunity oppty:[Select id,amount,accountId,Secondary_owner__c,account.CSS_ListingTel__c,account.name,account.CSS_CustomerID__c,ownerId,Override_Amount__c,Secondary_owner__r.ATTUID__c ,owner.ATTUID__c from Opportunity 
                               where account.CSS_CustomerID__c IN: csscustidSet AND 
                               Secondary_owner__r.ATTUID__c IN: attuidSet AND RecordtypeId =: nmrOpptyRecordTypeID AND(StageName= 'Stage 0 - Proposal Pending creation' OR StageName ='Stage 2 - Negotiation' OR StageName='Stage 3 - Commitment' OR StageName='Stage 1 - Proposal Created')]){
                    OpptyListSelected.add(oppty);
                    }
        return OpptyListSelected;
    }
    
    Public static void updateOppty(Map<Id,Double> updateproposalMap, Set<string> OpptyId){
        List<Opportunity> updateOpptyList = new List<Opportunity>();
        for(Opportunity oppty: [Select Id, Amount, Override_Amount__c from Opportunity where Id in: OpptyId ]){
            if(oppty.Override_Amount__c==Null){
                oppty.Amount = updateproposalMap.get(oppty.Id);
                updateOpptyList.add(oppty);
            }
        }
        update updateOpptyList;
    }
}